<?php
namespace App\Http\Controllers\Test\Design;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

/**
  设计模式之管道模式
 */

class PipeController extends Controller
{
  //
  public function show()
  {
    // 管道处理流程
    $worker = new Client();
    $worker->then(); // 理解页面输出顺序的原理
  }
}


// 代码略丑陋
interface RequestInterface
{
  // 我们之前讲过装饰者模式，这里是通过闭包函数实现 === 概念并不清楚
  // 通过之后实现类及调用就可以看出
  public static function handle($next);
}

class Request1 implements RequestInterface
{
  public static function handle($next)
  {
    echo "Request1 Begin." . "<br />";
    $next();
    echo "Request1 End." . "<br />";
  }
}

class Request2 implements RequestInterface
{
  public static function handle($next)
  {
    echo "Request2 Begin." . "<br />";
    $next();
    echo "Request2 End." . "<br />";
  }
}

class Request3 implements RequestInterface
{
  public static function handle($next)
  {
    echo "Request3 Begin." . "<br />";
    $next();
    echo "Request3 End." . "<br />";
  }
}

class Request4 implements RequestInterface
{
  public static function handle($next)
  {
    echo "Request4 Begin." . "<br />";
    $next();
    echo "Request4 End." . "<br />";
  }
}

class Client
{
  // 这里包含了所有的请求
  private $pipes = [
    '\App\Http\Controllers\Test\Design\Request1',
    '\App\Http\Controllers\Test\Design\Request2',
    '\App\Http\Controllers\Test\Design\Request3',
    '\App\Http\Controllers\Test\Design\Request4',
  ];

  // 这里就是思维导图中默认返回的匿名回调函数
  private function defaultClosure()
  {
    return function () {
      echo '请求处理中...' . "<br />";
    };
  }

  // 这里就是整个请求处理管道的关键
  private function getSlice()
  {
    return function ($stack, $pipe)
    {
      return function () use ($stack, $pipe)
      {
        return $pipe::handle($stack);
      };
    };
  }

  // 这里是负责发起请求处理
  public function then()
  {
    call_user_func(array_reduce($this->pipes, $this->getSlice(), $this->defaultClosure()));
  }
}